package com.c2b.algorithm.leetcode.base;

import java.util.Arrays;

/**
 * <a href='https://leetcode.cn/problems/determine-if-two-strings-are-close/'>确定两个字符串是否接近(Determine if Two Strings Are Close)</a>
 * <p>
 * 如果可以使用以下操作从一个字符串得到另一个字符串，则认为两个字符串 接近 ：
 * <pre>
 *  操作 1：交换任意两个 现有 字符。
 *      例如，abcde -> aecdb
 *  操作 2：将一个 现有 字符的每次出现转换为另一个 现有 字符，并对另一个字符执行相同的操作。
 *      例如，aacabb -> bbcbaa（所有 a 转化为 b ，而所有的 b 转换为 a ）
 * </pre>
 * 你可以根据需要对任意一个字符串多次使用这两种操作。
 * </p>
 * <p>给你两个字符串，word1 和 word2 。如果 word1 和 word2 接近 ，就返回 true ；否则，返回 false 。</p>
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例 1：
 *      输入：word1 = "abc", word2 = "bca"
 *      输出：true
 *      解释：2 次操作从 word1 获得 word2 。
 *          执行操作 1："abc" -> "acb"
 *          执行操作 1："acb" -> "bca"
 *
 * 示例 2：
 *      输入：word1 = "a", word2 = "aa"
 *      输出：false
 *      解释：不管执行多少次操作，都无法从 word1 得到 word2 ，反之亦然。
 *
 * 示例 3：
 *      输入：word1 = "cabbba", word2 = "abbccc"
 *      输出：true
 *      解释：3 次操作从 word1 获得 word2 。
 *          执行操作 1："cabbba" -> "caabbb"
 *          执行操作 2："caabbb" -> "baaccc"
 *          执行操作 2："baaccc" -> "abbccc"
 *
 * 示例 4：
 *      输入：word1 = "cabbba", word2 = "aabbss"
 *      输出：false
 *      解释：不管执行多少次操作，都无法从 word1 得到 word2 ，反之亦然。
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 * <ul>
 *     <li>1 <= word1.length, word2.length <= 10^5</li>
 *     <li>word1 和 word2 仅包含小写英文字母</li>
 * </ul>
 * </p>
 *
 * @author c2b
 * @since 2023/11/10 15:39
 */
public class LC1657DetermineIfTwoStringsAreClose_M {

    static class Solution {
        /**
         * <ul>
         *     <li>两字符串的长度相同</li>
         *     <li>两字符串的字符种类相同， 例如，对于某个字符，要么都有，要么都没有。</li>
         *     <li>字符频次相同。跟具体是什么字符无关，只要频次相同即可。</li>
         * </ul>
         */
        public boolean closeStrings(String word1, String word2) {
            // 校验两字符长度不同
            if (word1.length() != word2.length()) {
                return false;
            }
            // 校验两字符串的种类是否相同
            int[] arr1 = new int[26];
            int[] arr2 = new int[26];
            for (char ch : word1.toCharArray()) {
                arr1[ch - 'a']++;
            }
            for (char ch : word2.toCharArray()) {
                arr2[ch - 'a']++;
            }
            for (int i = 0; i < 26; i++) {
                // word1 出现的字符 word2 没有出现。
                // word2 出现的字符 word1 没有出现
                if ((arr1[i] == 0 && arr2[i] != 0) || (arr1[i] != 0 && arr2[i] == 0)) {
                    return false;
                }
            }
            // 校验两字符中频次是否相同
            Arrays.sort(arr1);
            Arrays.sort(arr2);
            for (int i = 0; i < 26; i++) {
                if (arr1[i] != arr2[i]) {
                    return false;
                }
            }
            return true;
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.closeStrings("abc", "bca"));
        System.out.println(solution.closeStrings("a", "aa"));
        System.out.println(solution.closeStrings("cabbba", "abbccc"));
        System.out.println(solution.closeStrings("cabbba", "aabbss"));
    }
}
